home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / mtools.lha / mtools-2.0.7 / mcopy.c < prev    next >
C/C++ Source or Header  |  1992-09-10  |  5KB  |  213 lines

  1. /*
  2.  * A front-end to the mread/mwrite commands.
  3.  *
  4.  * Emmet P. Gray            US Army, HQ III Corps & Fort Hood
  5.  * ...!uunet!uiucuxc!fthood!egray    Attn: AFZF-DE-ENV
  6.  * fthood!egray@uxc.cso.uiuc.edu    Directorate of Engineering & Housing
  7.  *                     Environmental Management Office
  8.  *                     Fort Hood, TX 76544-5057
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include <ctype.h>
  13. #include <sys/types.h>
  14. #include <sys/wait.h>
  15. #include "patchlevel.h"
  16.  
  17. #define NONE    0
  18. #define MREAD    1
  19. #define MWRITE    2
  20. #define MKDIR
  21.  
  22. #ifndef WEXITSTATUS
  23. #define WEXITSTATUS(x) (((x)>>8)&0xff)
  24. #endif /* WEXITSTATUS */
  25.  
  26. main(argc, argv)
  27. int argc;
  28. char *argv[];
  29. {
  30.     extern int optind;
  31.     extern char *optarg;
  32.     int i, oops, msdos_args, unix_args, destination;
  33.     char **nargv, *malloc();
  34.     void exit();
  35.                     /* get command line options */
  36.     msdos_args = 0;
  37.     unix_args = 0;
  38.     oops = 0;
  39.     while ((i = getopt(argc, argv, "tnvm")) != EOF) {
  40.         switch (i) {
  41.             case 't':
  42.             case 'n':
  43.             case 'v':
  44.             case 'm':
  45.                 break;
  46.             default:
  47.                 oops = 1;
  48.                 break;
  49.         }
  50.     }
  51.  
  52.     if (oops || (argc - optind) < 2) {
  53.         fprintf(stderr, "Mtools version %s, dated %s\n", VERSION, DATE);
  54.         fprintf(stderr, "Usage: %s [-tnvm] sourcefile targetfile\n", argv[0]);
  55.         fprintf(stderr, "       %s [-tnvm] sourcefile [sourcefiles...] targetdirectory\n", argv[0]);
  56.         exit(1);
  57.     }
  58.                     /* last file determines the direction */
  59.     if (argv[argc - 1][1] == ':')
  60.         destination = MWRITE;
  61.     else
  62.         destination = MREAD;
  63.  
  64.                     /* count the arguments */
  65.     for (i = optind; i < argc; i++) {
  66.         if (argv[i][1] == ':')
  67.             msdos_args++;
  68.         else
  69.             unix_args++;
  70.     }
  71.  
  72.     if (destination == MREAD && unix_args > 1) {
  73.         fprintf(stderr, "%s: Duplicate destination files\n", argv[0]); 
  74.         exit(1);
  75.     }
  76.                     /* chaining of mread and mwrite */
  77.     if (destination == MWRITE && msdos_args > 1)
  78.         chain(argc, argv);
  79.  
  80.     /*
  81.      * Copy the *argv[] array in case your Unix doesn't end the array
  82.      * with a null when it passes it to main()
  83.      */
  84.     nargv = (char **) malloc((unsigned int) (argc + 1) * sizeof(*argv));
  85.     nargv[0] = "mcopy";
  86.     for (i = 1; i < argc; i++)
  87.         nargv[i] = argv[i];
  88.     nargv[argc] = NULL;
  89.  
  90.     if (destination == MWRITE)
  91.         execvp("mwrite", nargv);
  92.     else
  93.         execvp("mread", nargv);
  94. }
  95.  
  96. chain(argc, argv)
  97. int argc;
  98. char *argv[];
  99. {
  100.     extern int optind;
  101.     int i, j, pid, status_read, status_write;
  102.     char *tmpdir, *mktemp(), **nargv, *malloc(), buf[256], *strcpy();
  103.     char *unixname(), *realloc();
  104.     void exit();
  105.  
  106.     nargv = (char **) malloc((unsigned int) (argc + 4) * sizeof(*argv));
  107.     nargv[0] = "mread";
  108.     nargv[1] = "-n";
  109.                     /* copy only the msdos arguments */
  110.     j = 2;
  111.     for (i = optind; i < argc -1; i++) {
  112.         if (argv[i][1] == ':')
  113.             nargv[j++] = argv[i];
  114.     }
  115.                     /* create a temp directory */
  116.     tmpdir = mktemp("/tmp/mtoolsXXXXXX");
  117.     if (mkdir(tmpdir, 0777) < 0) {
  118.         perror("mkdir");
  119.         exit(1);
  120.     }
  121.  
  122.     nargv[j++] = tmpdir;
  123.     nargv[j] = NULL;
  124.  
  125.     printf("reading...\n");
  126.     if (!(pid = fork()))
  127.         execvp("mread", nargv);
  128.  
  129.     while (wait(&status_read) != pid)
  130.         ;
  131.                     /* we blew it... */
  132.     if (WEXITSTATUS(status_read) == 1)
  133.         exit(1);
  134.                     /* reconstruct the argv[] */
  135.     nargv[0] = "sh";
  136.     nargv[1] = "-c";
  137.     nargv[2] = (char *) malloc(7);
  138.     strcpy(nargv[2], "mwrite");
  139.  
  140.     j = 3;
  141.     for (i = 1; i < argc -1; i++) {
  142.         /*
  143.          * Substitute the msdos arguments for their unix
  144.          * counterparts that have already been copied to tmpdir.
  145.          */
  146.         if (argv[i][1] == ':')
  147.             sprintf(buf, "%s/%s", tmpdir, unixname(argv[i]));
  148.         else
  149.             strcpy(buf, argv[i]);
  150.  
  151.         nargv[2] = (char *) realloc(nargv[2], sizeof(nargv[2]) + sizeof(buf));
  152.         strcat(nargv[2], " ");
  153.         strcat(nargv[2], buf);
  154.     }
  155.                     /* protect last arg from expansion */
  156.     sprintf(buf, "'%s'", argv[i]);
  157.     nargv[2] = (char *) realloc(nargv[2], sizeof(nargv[2]) + sizeof(buf));
  158.     strcat(nargv[2], " ");
  159.     strcat(nargv[2], buf);
  160.  
  161.     nargv[3] = NULL;
  162.  
  163.     printf("writing...\n");
  164.     if (!(pid = fork()))
  165.         execvp("sh", nargv);
  166.  
  167.     while (wait(&status_write) != pid)
  168.         ;
  169.                     /* clobber the directory */
  170.     sprintf(buf, "rm -fr %s", tmpdir);
  171.     system(buf);
  172.     exit(WEXITSTATUS(status_write));
  173. }
  174.  
  175. char *
  176. unixname(filename)
  177. char *filename;
  178. {
  179.     char *s, *temp, *strcpy(), *strrchr(), buf[256];
  180.     static char ans[13];
  181.  
  182.     strcpy(buf, filename);
  183.     temp = buf;
  184.                     /* skip drive letter */
  185.     if (buf[0] && buf[1] == ':')
  186.         temp = &buf[2];
  187.                     /* find the last separator */
  188.     if (s = strrchr(temp, '/'))
  189.         temp = s + 1;
  190.     if (s = strrchr(temp, '\\'))
  191.         temp = s + 1;
  192.                     /* xlate to lower case */
  193.     for (s = temp; *s; ++s) {
  194.         if (isupper(*s))
  195.             *s = tolower(*s);
  196.     }
  197.  
  198.     strcpy(ans, temp);
  199.     return(ans);
  200. }
  201.  
  202. #ifdef MKDIR
  203. /* ARGSUSED */
  204. mkdir(path, mode)
  205. char *path;
  206. int mode;
  207. {
  208.     char buf[256];
  209.     sprintf(buf, "mkdir %s", path);
  210.     return(system(buf));
  211. }
  212. #endif /* MKDIR */
  213.